﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Tools.Ribbon;
using Excel = Microsoft.Office.Interop.Excel;
using ExcelTools = Microsoft.Office.Tools.Excel;

namespace Observer
{
    class ExcelObserver
    {
        Dictionary<string, List<ExcelTools.ListObject>> _sheetToListObjects;
        Excel.Application _app;
        List<RibbonButton> _navigateButtons;
        RibbonLabel _lblTableName;
        RibbonButton _btnSetView;
        Dictionary<string, RibbonLabel> _tableNameToLabel;
        RibbonDropDown _dropDownEntriesPerList;

        public ExcelObserver(Excel.Application app, RibbonButton btnSetView, List<RibbonButton> navigateButtons, Dictionary<string, RibbonLabel> tableNameToLabel, RibbonDropDown dropDownEntriesPerList)
        {
            _app = app;
            _navigateButtons = navigateButtons;
            _tableNameToLabel = tableNameToLabel;
            _btnSetView = btnSetView;
            _dropDownEntriesPerList = dropDownEntriesPerList;
            _sheetToListObjects = new Dictionary<string, List<ExcelTools.ListObject>>();
            
            _app.SheetSelectionChange += new Excel.AppEvents_SheetSelectionChangeEventHandler(Application_SheetSelectionChange);
            _app.WorkbookNewSheet += new Excel.AppEvents_WorkbookNewSheetEventHandler(Application_WorkbookNewSheet);
            
            foreach (Excel.Worksheet worksheet in _app.ActiveWorkbook.Worksheets)
            {
                _sheetToListObjects[worksheet.Name] = new List<ExcelTools.ListObject>();
                System.Diagnostics.Debug.WriteLine("ExcelObserver. Sheet name: " + worksheet.Name);
            }
        }
        public void StopObserv()
        {
            _app.SheetSelectionChange -= new Excel.AppEvents_SheetSelectionChangeEventHandler(Application_SheetSelectionChange);
            _app.WorkbookNewSheet -= new Excel.AppEvents_WorkbookNewSheetEventHandler(Application_WorkbookNewSheet);
        }
        public void StartObserv()
        {
            _app.SheetSelectionChange += new Excel.AppEvents_SheetSelectionChangeEventHandler(Application_SheetSelectionChange);
            _app.WorkbookNewSheet += new Excel.AppEvents_WorkbookNewSheetEventHandler(Application_WorkbookNewSheet);
        }
        public void AddListObject(string sheetname, ExcelTools.ListObject listObject)
        {
            _sheetToListObjects[sheetname].Add(listObject);
        }
        public void RemoveListObject(string sheetName, string loName)
        {
            List<ExcelTools.ListObject> listObjects = _sheetToListObjects[sheetName];
            int k;
            for (k = 0; k < listObjects.Count; k++)
                if (listObjects[k].Name == loName)
                    break;
            if (k != listObjects.Count)
                listObjects.RemoveAt(k);
        }
        void Application_WorkbookNewSheet(Excel.Workbook workbook, object sheet)
        {
            Excel.Worksheet worksheet = sheet as Excel.Worksheet;
            _sheetToListObjects[worksheet.Name] = new List<ExcelTools.ListObject>();
#if DEBUG
            string info = string.Format("Application_WorkbookNewSheet. Workbook:{0}, Worksheet:{1}", workbook.Name, worksheet.Name);
            System.Diagnostics.Debug.WriteLine(info);
#endif
        }
        void Application_SheetSelectionChange(object sheet, Excel.Range target)
        {
            Excel.Worksheet worksheet = sheet as Excel.Worksheet;

            HandleSelectionChange(worksheet, target);
#if DEBUG
            string info = worksheet.Name + ":" +
    target.get_Address(Type.Missing, Type.Missing, Excel.XlReferenceStyle.xlA1, Type.Missing, Type.Missing);
            System.Diagnostics.Debug.WriteLine("Application_SheetSelectionChange: " + info);
#endif
        }

        private void HandleSelectionChange(Excel.Worksheet worksheet, Excel.Range target)
        {
            string sheetName = worksheet.Name;
            List<ExcelTools.ListObject> listObjects = _sheetToListObjects[sheetName];
            foreach (var listObject in listObjects)
            {
                Excel.Range result = _app.Intersect(target, listObject.Range);
                string addressTarget = target.get_Address(Type.Missing, Type.Missing, Excel.XlReferenceStyle.xlA1, Type.Missing, Type.Missing);
                string addressListObject = listObject.Range.get_Address(Type.Missing, Type.Missing, Excel.XlReferenceStyle.xlA1, Type.Missing, Type.Missing);
                string info = String.Format("HandleSelectionChange. Worksheet:{0}, Selection Address: {1}, ListObject Address: {2}, ListObject Name: {3}", worksheet.Name, addressTarget, addressListObject, listObject.Name);
                System.Diagnostics.Debug.WriteLine(info);

                if (result != null)
                {
                    info = String.Format("HandleSelectionChange. Selection: {0} inside ListObject: {1}, Name: {2}", addressTarget, addressListObject, listObject.Name);
                    System.Diagnostics.Debug.WriteLine(info);
                    ExcelDbAddIn.Globals.ThisAddIn.currLOName = listObject.Name;
                    foreach (var navigateButton in _navigateButtons)
                    {
                        navigateButton.Enabled = true;
                    }
                    TableInfo.TableInfo currTableInfo = ExcelDbAddIn.Globals.ThisAddIn._loNameToTableInfo[listObject.Name];

                    _tableNameToLabel["NumEntries"].Label = currTableInfo._cntEntries.ToString();
                    _tableNameToLabel["CurPage"].Label = currTableInfo._nPage.ToString();
                    _tableNameToLabel["TableName"].Label = currTableInfo._listObjectMaker.Name;
                    _btnSetView.Enabled = true;
                    if (currTableInfo._endRow == -1)
                        _dropDownEntriesPerList.SelectedItemIndex = 5;
                    else
                        _dropDownEntriesPerList.SelectedItemIndex = currTableInfo._entriesPerPage / 10 - 1;
                    _dropDownEntriesPerList.Enabled = true;
                    return;
                }
            }
            foreach (var navigateButton in _navigateButtons)
            {
                navigateButton.Enabled = false;
            }
            _tableNameToLabel["NumEntries"].Label = "";
            _tableNameToLabel["CurPage"].Label = "";
            _tableNameToLabel["TableName"].Label = "";
            _dropDownEntriesPerList.Enabled = false;
            _dropDownEntriesPerList.SelectedItemIndex = 0;
            _btnSetView.Enabled = false;

        }

    }
}
